#pragma once

#include <stdint.h>


namespace evm { namespace units {

// compile-time power
template<class T>
inline constexpr T pow(const T base, const unsigned exponent) {
    return (exponent == 0) ? 1 : (base * pow(base, exponent - 1));
}

// Binary unit constants.
// "Binary kilo unit"
constexpr int64_t Ki = 1024;
// "Binary mega unit"
constexpr int64_t Mi = pow(Ki, 2);
// "Binary giga unit"
constexpr int64_t Gi = pow(Ki, 3);
// "Binary tera unit"
constexpr int64_t Ti = pow(Ki, 4);
// "Binary peta unit"
constexpr int64_t Pi = pow(Ki, 5);
// "Binary exa unit"
constexpr int64_t Ei = pow(Ki, 6);
// "Binary zetta unit"
// constexpr int64_t Zi = pow(Ki, 7);  // overflow in constant expression
// "Binary yotta unit"
// constexpr int64_t Yi = pow(Ki, 8);

// Decimal unit constants.
// "Decimal kilo unit"
constexpr int64_t K = 1000;
// "Decimal mega unit"
constexpr int64_t M = pow(K, 2);
// "Decimal giga unit"
constexpr int64_t G = pow(K, 3);
// "Decimal tera unit"
constexpr int64_t T = pow(K, 4);
// "Decimal peta unit"
constexpr int64_t P = pow(K, 5);
// "Decimal exa unit"
constexpr int64_t E = pow(K, 6);
// "Decimal zetta unit"
// constexpr int64_t Z = pow(K, 7);
// "Decimal yotta unit"
// constexpr int64_t Y = pow(K, 8);

}}
